package com.mazaiting.generator.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mazaiting.common.core.domain.result.Option;
import com.mazaiting.common.core.domain.result.ResultCode;
import com.mazaiting.common.core.ex.exceptions.BaseException;
import com.mazaiting.common.core.ex.exceptions.BusinessException;
import com.mazaiting.common.core.ex.exceptions.EmptyObjectException;
import com.mazaiting.generator.config.GeneratorProperties;
import com.mazaiting.generator.constants.GenConstant;
import com.mazaiting.generator.converter.ITemplateFileConverter;
import com.mazaiting.generator.domain.entity.TemplateFileEntity;
import com.mazaiting.generator.domain.form.TemplateFileForm;
import com.mazaiting.generator.domain.query.TemplateFileQuery;
import com.mazaiting.generator.domain.vo.TemplateFileVO;
import com.mazaiting.generator.mapper.ITemplateFileMapper;
import com.mazaiting.generator.service.ITemplateFileService;
import com.mazaiting.generator.utils.GenUtil;
import com.mazaiting.mybatisplus.domain.vo.BasePageVO;
import com.mazaiting.web.domain.SingleResult;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.io.File;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * 模板配置
 *
 * @author mazaiting
 * @datetime 2022-11-11 23:16:16
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TemplateFileServiceImpl extends ServiceImpl<ITemplateFileMapper, TemplateFileEntity> implements ITemplateFileService {
    private final ITemplateFileConverter templateFileConvert;
    private final GeneratorProperties generatorProperties;

    @Override
    public BasePageVO<TemplateFileVO> page(TemplateFileQuery templateFileQuery) {
        // 分页数据
        Page<TemplateFileEntity> page = lambdaQuery()
                .eq(Objects.nonNull(templateFileQuery.getTemplateGroupId()),
                        TemplateFileEntity::getGroupId, templateFileQuery.getTemplateGroupId())
            .page(new Page<>(templateFileQuery.getPageNum(), templateFileQuery.getPageSize()));
        // entity -> vo
        Page<TemplateFileVO> voPage = templateFileConvert.entity2VO(page);

        return BasePageVO.success(voPage);
    }

    @Override
    public boolean save(TemplateFileForm templateFileForm) throws BusinessException {
        saveFile(templateFileForm);
        // form -> entity
        TemplateFileEntity entity = templateFileConvert.form2Entity(templateFileForm);
        entity.setId(null);
        entity.setLocation(1);
        return save(entity);
    }

    @Override
    public boolean update(TemplateFileForm templateFileForm) throws BaseException {
        // 根据 ID 查询查询实体
        TemplateFileEntity entity = getById(templateFileForm.getId());
        if (Objects.isNull(entity)) {
            log.warn("实体不存在");
            throw new EmptyObjectException(ResultCode.COMMON_FAIL.getCode(), "数据不存在");
        }
        saveFile(templateFileForm);
        // form -> entity
        templateFileConvert.form2Entity(templateFileForm);
        return updateById(entity);
    }

    @Override
    public boolean deleteByIds(String ids) {
        List<Long> idList = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
        return removeByIds(idList);
    }

    @Override
    public TemplateFileVO getInfoById(Long id) throws EmptyObjectException {
        TemplateFileEntity templateFileEntity = getById(id);
        if (Objects.isNull(templateFileEntity)) {
            log.warn("实体信息不存在");
            throw new EmptyObjectException(ResultCode.COMMON_FAIL.getCode(), "文件 ID 不存在");
        }
        return templateFileConvert.entity2VO(templateFileEntity);
    }


    @Override
    public List<Option<Long>> listFiles(String groupId) throws BusinessException {
        // 获取选项列表
        List<Option<Long>> optionList = lambdaQuery()
                .select(TemplateFileEntity::getId, TemplateFileEntity::getTitle)
                .eq(TemplateFileEntity::getGroupId, groupId)
                .list()
                .stream().map(entity -> new Option<>(entity.getId(), entity.getTitle())).toList();
        if (CollectionUtils.isEmpty(optionList)) {
            throw new BusinessException(ResultCode.COMMON_FAIL.getCode(), "无可用模板文件, 请先添加模板文件");
        }
        return optionList;
    }

    @Override
    public SingleResult getFileContent(String fileId) throws EmptyObjectException {
        TemplateFileEntity templateFileEntity = getById(fileId);
        if (Objects.isNull(templateFileEntity)) {
            log.warn("实体信息不存在");
            throw new EmptyObjectException(ResultCode.COMMON_FAIL.getCode(), "文件 ID 不存在");
        }
        return new SingleResult(GenUtil.getFileContent(generatorProperties, templateFileEntity));
    }

    /**
     * 保存文件
     * @param templateFileForm 表单数据
     * @throws BusinessException
     */
    private void saveFile(TemplateFileForm templateFileForm) throws BusinessException {
        try {
            // 文件保存路径 ${user.dir}/.generator/{groupId}/{form.filePath}
            String filePath = GenConstant.USER_DIRECTORY + File.separator + templateFileForm.getGroupId();
            if (StringUtils.hasLength(templateFileForm.getFilePath())) {
                filePath = filePath + File.separator + templateFileForm.getFilePath();
            }
            // 创建文件夹
            File fileDir = new File(filePath);
            // 不存在就遍历创建
            if (!fileDir.exists()) {
                boolean mkdirs = fileDir.mkdirs();
                log.info("文件路径创建结果: " + mkdirs);
            }
            File file = new File(fileDir, templateFileForm.getFileName());
            log.info("文件路径: " + file.getAbsolutePath());
            templateFileForm.getFile().transferTo(file);
        } catch (Exception e) {
            throw new BusinessException(ResultCode.COMMON_FAIL.getCode(), "文件保存失败.");
        }
    }
}